#include <iostream>
#include <ostream>

using namespace std;

class OutOfRange {
    private:
        int len;
        int index;
        int flag; // flag == 1 数组空，flag == 2 数组越界

    public:
        OutOfRange() : flag(1) {}
        OutOfRange(int len, int index) : len(len), index(index), flag(2) {}
        void what() const;
};

void OutOfRange::what() const
{
    if (1 == flag) 
        cout << "empty array" << endl;
    else if (2 == flag) 
        cout << "array index:0~" << len - 1 << ", but your index is " << index << "! out of range" << endl;
    else 
        cout << "unknow exception!" << endl;
}

template <typename T>
class ArrayList {
    private:
        T *data;             // 存储数据的数组指针
        size_t size;         // 当前元素数量
        size_t capacity;     // 当前容量

        // 扩容函数
        void resize(size_t new_capacity);

    public:
        // 构造函数
        ArrayList() : data(new T[10]), size(0), capacity(10) {}

        // 带初始容量的构造函数
        ArrayList(size_t initial_capacity) : 
            data(new T[initial_capacity]), size(0), capacity(initial_capacity) {}

        // 析构函数
        ~ArrayList() { delete[] data; }

        // 拷贝构造函数
        ArrayList(const ArrayList &other);

        // 拷贝赋值运算符
        ArrayList &operator=(const ArrayList &other);

        // 获取当前元素数量
        size_t getSize() const { return this->size; }

        // 获取当前容量
        size_t getCapacity() const { return this->capacity; }

        // 检查是否为空
        bool isEmpty() const { return this->size == 0; }

        // 重载[]运算符
        T &operator[](size_t index)
            { if (index < 0 || index >= size) throw OutOfRange(size, index); return data[index]; }

        // 重载[]运算符 (const版本)
        const T &operator[](size_t index) const 
            { if (index < 0 || index >= size) throw OutOfRange(size, index); return data[index]; }

        // 在末尾添加元素
        void add(const T &element);

        // 清空数组元素
        void clear() { size = 0; }

        template <typename TP>
        friend ostream &operator<<(ostream &out, ArrayList<TP> &a);
};

template <typename T>
void ArrayList<T>::resize(size_t new_capacity) 
{
    size_t i;
    T *new_data = new T[new_capacity];

    for (i = 0; i < size; ++i)
        new_data[i] = data[i];

    delete[] data;
    data = new_data;
    capacity = new_capacity;
}


template <typename T>
ArrayList<T>::ArrayList(const ArrayList &other) : data(new T[other.capacity]), size(other.size), capacity(other.capacity)
{
    size_t i;
    for (i = 0; i < size; ++i)
        data[i] = other.data[i];
}

template <typename T>
ArrayList<T> &ArrayList<T>::operator=(const ArrayList &other) 
{
    size_t i;

    if (this != &other) {
        delete[] data;
        data = new T[other.capacity];
        size = other.size;
        capacity = other.capacity;
        for (i = 0; i < size; ++i)
            data[i] = other.data[i];
    }

    return *this;
}

template <typename T>
void ArrayList<T>::add(const T &element)
{
    if (this->size == this->capacity) 
        resize(this->capacity * 2); // 通常扩容为原来的2倍

    data[this->size++] = element;
}

template <typename TP>
ostream &operator<<(ostream &out, ArrayList<TP> &a)
{
    size_t i;

    for (i = 0; i < a.size; i++)
        out << (a.data)[i] << " ";

    return out;
}

// 测试代码
int main() 
{
    int i;
    ArrayList<int> list;
    ArrayList<int> list2;

    // 测试添加元素
    for (i = 0; i < 20; ++i) {
        list.add(i * 10);
    }

    cout << "Size: " << list.getSize() << ", Capacity: " << list.getCapacity() << endl;

    // 测试访问元素
    cout << list << endl;

    list2 = list;
    list2.add(1);
    list2.add(2);

    cout << list2 << endl;

    try {
        // 可能异常的代码
        i = list[100];
    } catch (OutOfRange &e) {
        e.what();
    }

    return 0;
}

